using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 范围Slider控制器：实现物体拖拽功能，并在物体进入指定范围内时降低Slider数值
/// </summary>
[RequireComponent(typeof(Collider))]
public class RangeSliderController : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler
{
    [Header("引用设置")]
    [Tooltip("需要控制的Slider组件")]
    public Slider targetSlider;

    [Tooltip("作为范围检测区域的目标物体")]
    public Transform rangeTarget;

    [Header("范围设置")]
    [Tooltip("检测范围半径")]
    public float detectionRange = 5f;

    [Tooltip("在范围内时Slider数值降低的速率（每秒）")]
    public float sliderDecreaseRate = 0.1f;

    [Tooltip("Slider数值的最小值")]
    public float minSliderValue = 0f;

    [Header("拖拽设置")]
    [Tooltip("是否允许拖拽当前物体")]
    public bool isDraggable = true;

    [Tooltip("拖拽时是否忽略Y轴（仅在XZ平面移动）")]
    public bool ignoreYAxis = true;

    // 拖拽相关变量
    private bool isDragging = false;
    private Vector3 offset;
    private Camera mainCamera;

    // 范围检测相关变量
    private bool isInRange = false;

    /// <summary>
    /// 初始化组件和变量
    /// </summary>
    private void Start()
    {
        // 获取主相机
        mainCamera = Camera.main;
        if (mainCamera == null)
        {
            Debug.LogError("场景中没有主相机，请确保存在一个标签为MainCamera的相机");
        }

        // 确保碰撞体已启用并设置为触发器
        Collider collider = GetComponent<Collider>();
        if (collider != null)
        {
            collider.isTrigger = true;
        }
        else
        {
            Debug.LogError("RangeSliderController需要一个Collider组件");
        }

        // 验证Slider引用
        if (targetSlider == null)
        {
            Debug.LogError("未指定目标Slider，请在Inspector中为RangeSliderController组件赋值targetSlider字段");
        }

        // 验证范围目标引用
        if (rangeTarget == null)
        {
            Debug.LogError("未指定范围目标，请在Inspector中为RangeSliderController组件赋值rangeTarget字段");
        }
    }

    /// <summary>
    /// 每帧更新检测物体是否在范围内，并在范围内降低Slider数值
    /// </summary>
    private void Update()
    {
        // 检查是否在范围内
        CheckIfInRange();

        // 如果在范围内且Slider引用有效，则降低Slider数值
        if (isInRange && targetSlider != null)
        {
            targetSlider.value = Mathf.Max(minSliderValue, targetSlider.value - sliderDecreaseRate * Time.deltaTime);
        }
    }

    /// <summary>
    /// 检查当前物体是否在范围目标的检测范围内
    /// </summary>
    private void CheckIfInRange()
    {
        if (rangeTarget != null)
        {
            float distance = Vector3.Distance(transform.position, rangeTarget.position);
            isInRange = distance <= detectionRange;
        }
    }

    /// <summary>
    /// 当鼠标按下物体时开始拖拽
    /// </summary>
    /// <param name="eventData">事件数据</param>
    public void OnPointerDown(PointerEventData eventData)
    {
        if (!isDraggable || mainCamera == null)
            return;

        // 计算物体与鼠标点击位置之间的偏移
        Ray ray = mainCamera.ScreenPointToRay(eventData.position);
        if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity))
        {
            offset = transform.position - hit.point;
            isDragging = true;
        }
    }

    /// <summary>
    /// 拖拽物体时更新位置
    /// </summary>
    /// <param name="eventData">事件数据</param>
    public void OnDrag(PointerEventData eventData)
    {
        if (!isDragging || !isDraggable || mainCamera == null)
            return;

        // 计算拖拽位置
        Ray ray = mainCamera.ScreenPointToRay(eventData.position);
        if (Physics.Raycast(ray, out RaycastHit hit, Mathf.Infinity))
        {
            Vector3 newPosition = hit.point + offset;

            // 如果忽略Y轴，则保持当前Y坐标
            if (ignoreYAxis)
            {
                newPosition.y = transform.position.y;
            }

            transform.position = newPosition;
        }
    }

    /// <summary>
    /// 当鼠标释放时结束拖拽
    /// </summary>
    /// <param name="eventData">事件数据</param>
    public void OnPointerUp(PointerEventData eventData)
    {
        isDragging = false;
    }

    /// <summary>
    /// 在Scene视图中绘制Gizmos，显示检测范围
    /// </summary>
    private void OnDrawGizmosSelected()
    {
        // 绘制当前物体位置
        Gizmos.color = Color.blue;
        Gizmos.DrawWireSphere(transform.position, 0.5f);

        // 绘制范围目标和检测范围
        if (rangeTarget != null)
        {
            Gizmos.color = isInRange ? Color.red : Color.green;
            Gizmos.DrawWireSphere(rangeTarget.position, detectionRange);
            Gizmos.DrawLine(transform.position, rangeTarget.position);
        }
    }
}

/* 使用说明：
1. 将此脚本挂载到需要拖拽的物体上
2. 在Inspector面板中配置以下参数：
   - Target Slider: 拖拽需要控制的Slider组件
   - Range Target: 指定作为范围检测区域的目标物体
   - Detection Range: 设置检测范围半径
   - Slider Decrease Rate: 设置Slider数值降低的速率（每秒）
   - Min Slider Value: 设置Slider数值的最小值
   - Is Draggable: 勾选是否允许拖拽当前物体
   - Ignore Y Axis: 勾选是否在拖拽时忽略Y轴（仅在XZ平面移动）
3. 确保挂载脚本的物体有Collider组件（脚本会自动将其设置为触发器）
4. 运行场景后，可以拖拽物体，当物体进入Range Target的检测范围内时，Slider数值会自动降低

参数说明：
- targetSlider: 需要控制的Slider组件，必须指定
- rangeTarget: 作为范围检测区域的目标物体，必须指定
- detectionRange: 检测范围半径，默认为5米
- sliderDecreaseRate: Slider数值降低速率，默认为0.1/秒
- minSliderValue: Slider数值最小值，默认为0
- isDraggable: 是否允许拖拽，默认为true
- ignoreYAxis: 拖拽时是否忽略Y轴，默认为true

功能特点：
- 实现物体的鼠标拖拽功能
- 实时检测物体是否在指定范围内
- 在范围内时自动降低Slider数值
- 在Scene视图中绘制辅助Gizmos，显示检测范围和物体位置
- 包含完整的参数验证和错误日志输出
*/